#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include "dirops.h"
#include "object.h"
#include "util.h"

int dentry_lookup (object *dir, const char *name, dentry *d) {

  assert (dir->type == DIR_OBJ);
  int max = (dir->length)/(sizeof (dentry));
  int i;
  dentry *dentlist = (dentry *) dir->data;
  for (i=0; i<max; i++) {
    if (strcmp (dentlist[i].name, name) == 0) {
      memcpy (d, dentlist+i, sizeof (dentry));  /* Pointer addition */
      return 0;
    }
  }
  return -ENOENT;
}


/*
  If a particular name exists in DIR or not. Saves the headache of 
  allocating space for dentry and all.
  Returns 0 if exists, -1 otherwise.
*/
int name_exists (object *dir, const char *name) {
  assert (dir->type == DIR_OBJ);
  int ret = 0;
  dentry *d = malloc (sizeof (dentry));
  ret = dentry_lookup (dir, name, d);
  free (d);
  return ret;
}



int dentry_insert (object *dir, dentry *d) {

  assert (dir->type == DIR_OBJ);

  /* First we make sure the name does not already exist */
  if (name_exists (dir, d->name) == 0)
    return -EEXIST;

  /*
    Just allocating more memory, and copying stuff there is not 
    the perfect solution. This would cause problems in freeing
    up the space, as the caller would not know that this
    function has already freed up the memory 
  
    So we just copy it at the end, and make sure that there
    are only MAX_DATA_OBJ/(sizeof(dentry)) entries
  */

  if (dir->length + sizeof (dentry) > MAX_DATA_OBJ)
    return -ENOMEM;

  memcpy ((dir->data)+(dir->length), d, sizeof (dentry));
  dir->length += sizeof (dentry);
  
  return 0;
}

int dentry_delete (object *dir, const char *name) {

  assert (dir->type == DIR_OBJ);

  int i = 0, found = 0;
  int num_dentry = (dir->length)/(sizeof (dentry));
  dentry *dentlist = dir->data;

  while (i<num_dentry ) {
    if (found != 1) {
      /* Still haven't found what to delete */  
      if (strcmp (dentlist[i].name, name) == 0)
        found = 1;
    } else {
      /* Just shift this dentry */
      /*Pointer arithmetic*/
      memcpy (dentlist+(i-1), dentlist+i, sizeof (dentry)); 
    }
    i++;
  }

  if (found == 0)
    return -ENOENT;
  else 
    dir->length = dir->length - sizeof (dentry); 
  return 0;
  
}
